/////////////////////////////////////////////////////////////////////////////
// This file is part of the "Java-DAP" project, a Java implementation
// of the OPeNDAP Data Access Protocol.
//
// Copyright (c) 2007 OPeNDAP, Inc.
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
//
// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
/////////////////////////////////////////////////////////////////////////////
using System;
using System.Collections;
using System.Diagnostics;
using System.IO;
using System.Text;
using System.Xml;
using NDODS.DAP.BaseTypes;
using NDODS.DAP.Exceptions;
using NDODS.DAP.Parser;
using NDODS.DAP.Primitives;
using NDODS.DAP.Utils;
using NDODS.DAP.XMLParser;
using Debug=NDODS.Util.Debug;

namespace NDODS.DAP
{
    /// <summary> The OPeNDAP Data Descriptor Object (DDS) is a data structure used by
    /// the OPeNDAP software to describe datasets and subsets of those
    /// datasets.  The DDS may be thought of as the declarations for the
    /// data structures that will hold data requested by some OPeNDAP client.
    /// Part of the job of a OPeNDAP server is to build a suitable DDS for a
    /// specific dataset and to send it to the client.  Depending on the
    /// data access API in use, this may involve reading part of the
    /// dataset and inferring the DDS.  Other APIs may require the server
    /// simply to Read some ancillary data file with the DDS in it.
    /// <p/>
    /// On the server side, in addition to the data declarations, the DDS
    /// holds the clauses of any constraint expression that may have
    /// accompanied the data request from the OPeNDAP client.  The DDS object
    /// includes methods for modifying the DDS according to the given
    /// constraint expression.  It also has methods for directly modifying
    /// a DDS, and for transmitting it from a server to a client.
    /// <p/>
    /// For the client, the DDS object includes methods for reading the
    /// persistent form of the object sent from a server. This includes parsing
    /// the ASCII representation of the object and, possibly, reading data
    /// received from a server into a data object.
    /// <p/>
    /// Note that the class DDS is used to instantiate both DDS and DataDDS
    /// objects. A DDS that is empty (contains no actual data) is used by servers
    /// to send structural information to the client. The same DDS can becomes a
    /// DataDDS when data values are bound to the variables it defines.
    /// <p/>
    /// For a complete description of the DDS layout and protocol, please
    /// refer to <em>The OPeNDAP User Guide</em>.
    /// <p/>
    /// The DDS has an ASCII representation, which may be transmitted
    /// from a OPeNDAP server to a client.  Here is the DDS representation of
    /// an entire dataset containing a time series of worldwide grids of
    /// sea surface temperatures:
    /// <p/>
    /// <blockquote><pre>
    /// Dataset {
    /// Float64 lat[lat = 180];
    /// Float64 lon[lon = 360];
    /// Float64 time[time = 404];
    /// Grid {
    /// ARRAY:
    /// Int32 sst[time = 404][lat = 180][lon = 360];
    /// MAPS:
    /// Float64 time[time = 404];
    /// Float64 lat[lat = 180];
    /// Float64 lon[lon = 360];
    /// } sst;
    /// } weekly;
    /// </pre></blockquote>
    /// <p/>
    /// If the data request to this dataset includes a constraint
    /// expression, the corresponding DDS might be different.  For
    /// example, if the request was only for northern hemisphere data
    /// at a specific time, the above DDS might be modified to appear like
    /// this:
    /// <p/>
    /// <blockquote><pre>
    /// Dataset {
    /// Grid {
    /// ARRAY:
    /// Int32 sst[time = 1][lat = 90][lon = 360];
    /// MAPS:
    /// Float64 time[time = 1];
    /// Float64 lat[lat = 90];
    /// Float64 lon[lon = 360];
    /// } sst;
    /// } weekly;
    /// </pre></blockquote>
    /// <p/>
    /// Since the constraint has narrowed the area of interest, the range
    /// of latitude values has been halved, and there is only one time
    /// value in the returned array.  Note that the simple arrays (<em>lat</em>,
    /// <em>lon</em>, and <em>time</em>) described in the dataset are also part of
    /// the <em>sst</em> Grid object.  They can be requested by themselves or as
    /// part of that larger object.
    /// <h3>DDX</h3>
    /// The DDS also has an XML representation. This is known as a DDX. Since
    /// <code>BaseType</code> variables now each have their own set of <code>Attributes</code>
    /// it has become necessary to have a representation of the DDS that captures these
    /// relationships. Consider the previous example. A correctly constructed
    /// DAS for that DDS might look like:
    /// <blockquote><pre>
    /// Attributes {
    /// lat {
    /// String fullName "latitude";
    /// String units "degrees North";
    /// }
    /// lon {
    /// String fullName "longitude";
    /// String units "degrees East";
    /// }
    /// time {
    /// String units "seconds";
    /// }
    /// sst {
    /// String fullName "Sea Surface Temperature";
    /// String units "degrees centigrade";
    /// sst {
    /// Alias fullName .sst.fullName;
    /// Alias units .sst.units;
    /// }
    /// time {
    /// Alias units .time.units;
    /// }
    /// lat {
    /// Alias fullName .lat.fullName;
    /// Alias units .lat.units;
    /// }
    /// lon {
    /// Alias fullName .lon.fullName;
    /// Alias units .lon.units;
    /// }
    /// }
    /// }
    /// </pre></blockquote>
    /// <p/>
    /// <p/>
    /// Combined with the DDS and expressed as a DDX it would look like:
    /// <p/>
    /// <blockquote><pre>
    /// <p/>
    /// <?xml version="1.0" encoding="UTF-8"?>
    /// <Dataset name="weekly"
    /// xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    /// xmlns="http://xml.opendap.org/ns/DAP2"
    /// xsi:schemaLocation="http://xml.opendap.org/ns/DAP2  http://xml.opendap.org/dap/dap2.xsd" >
    /// <p/>
    /// <p/>
    /// <Array name="lat">
    /// <Attribute name="fullName" type="String">
    /// <value>&amp;quot;latitude&amp;quot;</value>
    /// </Attribute>
    /// <Attribute name="units" type="String">
    /// <value>&amp;quot;degrees North&amp;quot;</value>
    /// </Attribute>
    /// <Float64/>
    /// <dimension name="lat" size="180"/>
    /// </Array>
    /// <Array name="lon">
    /// <Attribute name="fullName" type="String">
    /// <value>&amp;quot;longitude&amp;quot;</value>
    /// </Attribute>
    /// <Attribute name="units" type="String">
    /// <value>&amp;quot;degrees East&amp;quot;</value>
    /// </Attribute>
    /// <Float64/>
    /// <dimension name="lon" size="360"/>
    /// </Array>
    /// <Array name="time">
    /// <Attribute name="units" type="String">
    /// <value>&amp;quot;seconds&amp;quot;</value>
    /// </Attribute>
    /// <Float64/>
    /// <dimension name="time" size="404"/>
    /// </Array>
    /// <Grid  name="sst">
    /// <Attribute name="fullName" type="String">
    /// <value>&amp;quot;Sea Surface Temperature&amp;quot;</value>
    /// </Attribute>
    /// <Attribute name="units" type="String">
    /// <value>&amp;quot;degrees centigrade&amp;quot;</value>
    /// </Attribute>
    /// <Array name="sst">
    /// <Alias name="fullName" Attribute=".sst.fullName"/>
    /// <Alias name="units" Attribute=".sst.units"/>
    /// <Int32/>
    /// <dimension name="time" size="404"/>
    /// <dimension name="lat" size="180"/>
    /// <dimension name="lon" size="360"/>
    /// </Array>
    /// <Map name="time">
    /// <Alias name="units" Attribute=".time.units"/>
    /// <Float64/>
    /// <dimension name="time" size="404"/>
    /// </Map>
    /// <Map name="lat">
    /// <Alias name="fullName" Attribute=".lat.fullName"/>
    /// <Alias name="units" Attribute=".lat.units"/>
    /// <Float64/>
    /// <dimension name="lat" size="180"/>
    /// </Map>
    /// <Map name="lon">
    /// <Alias name="fullName" Attribute=".lon.fullName"/>
    /// <Alias name="units" Attribute=".lon.units"/>
    /// <Float64/>
    /// <dimension name="lon" size="360"/>
    /// </Map>
    /// </Grid>
    /// <p/>
    /// <dataBLOB href="cid:ContentIdOfTheMIMEAttcahmentContainingTheDataBlob"/>
    /// </Dataset>
    /// <p/>
    /// <p/>
    /// </pre></blockquote>
    /// The DDX can also be sent from a server to a client.
    /// <p/>
    /// <h3>Using the DDS's API to construct a DDS</h3>
    /// Many developers choose not to use the <code>DDSParser</code> to
    /// build <code>DDS's</code> but to build them
    /// using the <code>DDS</code> API. This is typical of devlopers
    /// writing servers that work with
    /// information rich data formats such as NetCDF or HDF. With the
    /// addition of <code>Attributes</code>
    /// (and <code>Attribute</code> containers) to all of the datatypes in the DAP
    /// it is now possible to construct a <code>DDS</code>
    /// that contains all of the source meta-data from the original data source. This is
    /// an extremly useful thing. However, when building a <code>DDS</code>
    /// using the <code>DDS</code> API be sure
    /// to call the functions <code>DDS.CheckForAttributeNameConflict()</code> and
    /// <code>DDS.resolveAliases()</code></li> on the new DDS prior to releasing it from
    /// the code that builds it. Otherwise the DDS may have functional problems!
    /// <p/>
    /// <p/>
    /// See <em>The OPeNDAP User Guide</em>, or the documentation of the
    /// BaseType class for descriptions of the OPeNDAP data types.
    /// 
    /// </summary>
    /// <author>  ndp
    /// </author>
    /// <version>  $Revision: 15901 $
    /// </version>
    /// <seealso cref="BaseType">
    /// </seealso>
    /// <seealso cref="IBaseTypeFactory">
    /// </seealso>
    /// <seealso cref="DAS">
    /// </seealso>
    /// <seealso cref="DDSXMLParser">
    /// </seealso>
    /// <seealso cref="CheckForAttributeNameConflict">
    /// </seealso>
    /// <seealso cref="resolveAliases">
    /// </seealso>
    /// <opendap.ddx.experimental>  Many parts of this class have been modified to support </opendap.ddx.experimental>
    /// <summary> the DDX functionality. This API is going to change!
    /// </summary>
    [Serializable]
    public class DDS : DStructure, ICloneable
    {
        //UPGRADE_NOTE: Respective javadoc comments were merged.  It should be changed in order to comply with .NET documentation conventions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1199'"
        /// <summary> Get the Class factory.  This is the machine that builds classes
        /// for the internal representation of the data set.
        /// 
        /// </summary>
        /// <returns> the BaseTypeFactory.
        /// </returns>
        /// <summary> Get the Class factory.  This is the machine that builds classes
        /// for the internal representation of the data set.
        /// </summary>
        public virtual IBaseTypeFactory Factory {
            get { return factory; }

            set { factory = value; }
        }

        //UPGRADE_NOTE: Respective javadoc comments were merged.  It should be changed in order to comply with .NET documentation conventions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1199'"
        /// <summary> Get's the dataBLOB Contnet-ID for this DDS.
        /// The dataBLOB element has an attribute, href, which is used to reference the MIME part
        /// of a the Multipart MIME document in a DAP4 data response that contains the binary encoded
        /// data described by the DDX document.
        /// 
        /// </summary>
        /// <returns> A <code>String</code> containing the URL of the servers BLOB response for
        /// this DDS.
        /// </returns>
        /// <opendap.ddx.experimental>  </opendap.ddx.experimental>
        /// <summary> Set's the dataBLOB reference for this DDS.
        /// The dataBLOB element has an attribute, href, which is used to reference the MIME part
        /// of a the Multipart MIME document in a DAP4 data response that contains the binary encoded
        /// data described by the DDX document.
        /// 
        /// </summary>
        /// <opendap.ddx.experimental>  </opendap.ddx.experimental>
        public virtual String BlobContentID {
            get { return (_dataBlobID); }

            set { _dataBlobID = value; }
        }

        /// <summary> Creates a DAS object from the collection of <code>BaseType</code> variables and their
        /// associated <code>Attributes</code>. This DAS is correctly formed (vis-a-vis the DAP
        /// specification) for this DDS.
        /// 
        /// </summary>
        /// <returns> A correctly formed <code>DAS</code> object for this DDS.
        /// </returns>
        /// <seealso cref="DAS">
        /// </seealso>
        /// <seealso cref="BaseType">
        /// </seealso>
        /// <throws>  DASException </throws>
        public virtual DAS DAS {
            get {
                DAS myDAS = new DAS();

                try {
                    // Since the DDS can contain Attributes, in addtion to Attribute containers (AttributeTables)
                    // at the top (dataset) level and the DAS cannot, it is required that these Attributes be
                    // bundled into a container at the top level of the DAS.
                    // In the code that follows this container is called "looseEbds"

                    // Make the container.
                    AttributeTable looseEnds = new AttributeTable(LooseEndsTableName);

                    // Carfully populate it from the one at our top-level. Since we are using the
                    // API and also copying containers here in order to build a new version,
                    // we must use a clone of this (the DDS's) AttributeTable.
                    AttributeTable atTbl = (AttributeTable) AttributeTable.Clone();

                    int countLooseAttributes = 0;
                    // Work on each Attribute in the container.
                    IEnumerator e = atTbl.Names.GetEnumerator();
                    //UPGRADE_TODO: Method 'java.util.Enumeration.hasMoreElements' was converted to 'System.Collections.IEnumerator.MoveNext' which has a different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1073_javautilEnumerationhasMoreElements'"
                    while (e.MoveNext()) {
                        //UPGRADE_TODO: Method 'java.util.Enumeration.nextElement' was converted to 'System.Collections.IEnumerator.Current' which has a different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1073_javautilEnumerationnextElement'"
                        String aName = (String) e.Current;
                        Attribute a = atTbl.getAttribute(aName);

                        if (a.isAlias()) {
                            // copy an alias.
                            String name = a.Name;

                            String attribute = ((Alias) a).AliasedToAttributeFieldAsClearString;

                            looseEnds.addAlias(name, convertDDSAliasFieldsToDASAliasFields(attribute));
                            countLooseAttributes++;
                        }
                        else if (a.isContainer()) {
                            // A reference copy. This is why we are working with a clone.
                            myDAS.addAttributeTable(a.Name, a.getContainer());
                        }
                        else {
                            // copy an Attribute and it's values...

                            String name = a.Name;
                            int type = a.Type;

                            IEnumerator vals = a.Values;
                            //UPGRADE_TODO: Method 'java.util.Enumeration.hasMoreElements' was converted to 'System.Collections.IEnumerator.MoveNext' which has a different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1073_javautilEnumerationhasMoreElements'"
                            while (vals.MoveNext()) {
                                //UPGRADE_TODO: Method 'java.util.Enumeration.nextElement' was converted to 'System.Collections.IEnumerator.Current' which has a different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1073_javautilEnumerationnextElement'"
                                String value_Renamed = (String) vals.Current;
                                looseEnds.appendAttribute(name, type, value_Renamed, true);
                            }
                            countLooseAttributes++;
                        }
                    }

                    Trace.TraceInformation("Found " + countLooseAttributes + " top level Attributes.");

                    if (_Debug)
                        myDAS.print(Console.OpenStandardOutput());

                    // Only add this AttributeTable if actually contains Attributes!
                    if (countLooseAttributes > 0) {

                        Trace.TraceInformation("Creating looseEnds table: " + looseEnds.Name);
                        myDAS.addAttributeTable(looseEnds.Name, looseEnds);
                    }

                    // Walk through the variables at the top level.
                    e = Variables;
                    //UPGRADE_TODO: Method 'java.util.Enumeration.hasMoreElements' was converted to 'System.Collections.IEnumerator.MoveNext' which has a different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1073_javautilEnumerationhasMoreElements'"
                    while (e.MoveNext()) {
                        //UPGRADE_TODO: Method 'java.util.Enumeration.nextElement' was converted to 'System.Collections.IEnumerator.Current' which has a different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1073_javautilEnumerationnextElement'"
                        BaseType bt = (BaseType) e.Current;
                        // Build the correct AttributeTable for it at the Toplevel of the DAS
                        buildDASAttributeTable(bt, myDAS);
                    }

                    if (_Debug)
                        myDAS.print(Console.OpenStandardOutput());

                    // Make sure that the Aliases resolve correctly. Since we are moving from a
                    // DDS/DDX space to a DFAS space the Aliases may not be resolvable. In that
                    // case an exception will get thrown...
                    myDAS.resolveAliases();
                }
                catch (Exception e) {
                    SupportClass.WriteStackTrace(e, Console.Error);
                    //UPGRADE_TODO: The equivalent in .NET for method 'java.lang.Class.getName' may return a different value. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1043'"
                    //UPGRADE_TODO: The equivalent in .NET for method 'java.lang.Throwable.getMessage' may return a different value. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1043'"
                    throw new DASException(DAP2Exception.UNKNOWN_ERROR,
                                           "Could not create a DAS from this DDX object.\n" +
                                           "Because of the structural differences between the DDX and the DAS it is " +
                                           "possible for the DDX to contain sets of Attributes that cannot be represented " +
                                           "in a DAS object.\n" + "The specific problem was an execption of type " +
                                           e.GetType().FullName + " with an " + "error message of: \n" + e.Message);
                }

                return (myDAS);
            }
        }

        /// <summary> Make a name for an attribute table at the top level in which to
        /// place any loose attributes at the top level.
        /// 
        /// </summary>
        /// <returns>
        /// 
        /// </returns>
        private String LooseEndsTableName {
            get { return (checkLooseEndsTableNameConflict(this.Name, 0)); }
        }

        /// <summary> Returns an <code>Enumeration</code> of the dataset variables.
        /// 
        /// </summary>
        /// <returns> an <code>Enumeration</code> of <code>BaseType</code>.
        /// </returns>
        public override IEnumerator Variables {
            get { return vars.GetEnumerator(); }
        }

        /// <summary> This a wrapper method for <code>DDS.Print()</code>.
        /// 
        /// </summary>
        /// <returns> The output of <code>DDS.Print()</code> as
        /// <code>String</code>
        /// </returns>
        /// <seealso cref="Print(StreamWriter)">
        /// </seealso>
        public virtual String DDSText {
            get {
                MemoryStream sw = new MemoryStream(100);
                //UPGRADE_ISSUE: Constructor 'java.io.StreamWriter.StreamWriter' was not converted. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1000_javaioStreamWriterStreamWriter_javaioWriter'"
                this.Print(sw);
                return sw.ToString();
            }
        }

        /// <summary> This a wrapper method for <code>DDS.PrintXML()</code>.
        /// 
        /// </summary>
        /// <returns> The output of <code>DDS.PrintXML()</code> as
        /// <code>String</code>
        /// </returns>
        /// <seealso cref="PrintXML(StreamWriter)">
        /// </seealso>
        /// <opendap.ddx.experimental>  </opendap.ddx.experimental>
        public virtual String DDXText {
            get {
                MemoryStream sw = new MemoryStream(100);
                //UPGRADE_ISSUE: Constructor 'java.io.StreamWriter.StreamWriter' was not converted. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1000_javaioStreamWriterStreamWriter_javaioWriter'"
                this.PrintXML(sw);
                return sw.ToString();
            }
        }

        private const bool _Debug = false;

        // Used by resolveAliases()
        private BaseType currentBT;
        private AttributeTable currentAT;

        // Some handy definitons.
        private const char slash = '\\';
        private const char quote = '\"';
        private const char dot = '.';


        /// <summary> Factory for new DAP variables.</summary>
        private IBaseTypeFactory factory;


        private const String defaultSchemaLocation = "http://xml.opendap.org/dap/dap2.xsd";
        private const String opendapNameSpace = "http://xml.opendap.org/ns/DAP2";
        private String schemaLocation;


        private String _dataBlobID = null;

        /// <summary> Creates an empty <code>DDS</code>.</summary>
        public DDS() : this(null, new DefaultFactory()) {}

        /// <summary> Creates an empty <code>DDS</code> with the given dataset name.
        /// 
        /// </summary>
        /// <param name="n">the dataset name
        /// </param>
        public DDS(String n) : this(n, new DefaultFactory()) {}

        /// <summary> Creates an empty <code>DDS</code> with the given
        /// <code>BaseTypeFactory</code>.  This will be used for OPeNDAP servers which
        /// need to construct subclasses of the various <code>BaseType</code> objects
        /// to hold additional server-side information.
        /// 
        /// </summary>
        /// <param name="factory">the server <code>BaseTypeFactory</code> object.
        /// </param>
        public DDS(IBaseTypeFactory factory) : this("", factory) {}

        /// <summary> Creates an empty <code>DDS</code> with the given dataset name and
        /// <code>BaseTypeFactory</code>.  This will be used for OPeNDAP servers which
        /// need to construct subclasses of the various <code>BaseType</code> objects
        /// to hold additional server-side information.
        /// 
        /// </summary>
        /// <param name="n">      the dataset name
        /// </param>
        /// <param name="factory">the server <code>BaseTypeFactory</code> object.
        /// </param>
        public DDS(String n, IBaseTypeFactory factory) : this(n, factory, defaultSchemaLocation) {}

        /// <summary> Creates an empty <code>DDS</code> with the given dataset name and
        /// <code>BaseTypeFactory</code>.  This will be used for OPeNDAP servers which
        /// need to construct subclasses of the various <code>BaseType</code> objects
        /// to hold additional server-side information.
        /// 
        /// </summary>
        /// <param name="n">      the dataset name
        /// </param>
        /// <param name="factory">the server <code>BaseTypeFactory</code> object.
        /// </param>
        /// <param name="schema"> the URL where the parser can find an instance of the
        /// OPeNDAP namespace schema.
        /// </param>
        /// <opendap.ddx.experimental>  </opendap.ddx.experimental>
        public DDS(String n, IBaseTypeFactory factory, String schema) : base(n) {
            vars = ArrayList.Synchronized(new ArrayList(10));
            this.factory = factory;
            schemaLocation = schema;
        }

        /// <summary> Returns a clone of this <code>DDS</code>.  A deep copy is performed on
        /// all variables inside the <code>DDS</code>.
        /// 
        /// </summary>
        /// <returns> a clone of this <code>DDS</code>.
        /// </returns>
        public override Object Clone() {
            try {
                DDS d = (DDS) base.Clone();
                d.vars = ArrayList.Synchronized(new ArrayList(10));
                for (int i = 0; i < vars.Count; i++) {
                    BaseType element = (BaseType) vars[i];
                    d.vars.Add(element.Clone());
                }
                d.Name = this.Name;

                // Question:
                // What about copying the BaseTypeFactory?
                // Do we want a reference to the same one? Or another instance?
                // Is there a difference? Should we be building the clone
                // using "new DDS(getFactory())"??

                // Answer:
                // Yes. Use the same type factory!

                d.factory = this.factory;


                return d;
            }
                //	catch (CloneNotSupportedException e) {
            catch (Exception ) {
                // this shouldn't happen, since we are Cloneable
                throw new ApplicationException();
            }
        }


        /// <summary> This method just makes sure that the attribute field in each Aliases resolves correctly
        /// if there ends up being a "looseEnds" Attribute Table at the top level.
        /// 
        /// </summary>
        /// <param name="attribute">
        /// </param>
        /// <returns>
        /// </returns>
        /// <throws>  MalformedAliasException </throws>
        private String convertDDSAliasFieldsToDASAliasFields(String attribute) {
            String prefix = "";

            ArrayList aNames = tokenizeAliasField(attribute);

            // We know that the first token should be a dot, we look at the
            // second token to see if it references a variable in the DDS.

            String topName = (String) aNames[1];

            bool foundIt = false;
            IEnumerator e = Variables;
            //UPGRADE_TODO: Method 'java.util.Enumeration.hasMoreElements' was converted to 'System.Collections.IEnumerator.MoveNext' which has a different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1073_javautilEnumerationhasMoreElements'"
            while (e.MoveNext()) {
                //UPGRADE_TODO: Method 'java.util.Enumeration.nextElement' was converted to 'System.Collections.IEnumerator.Current' which has a different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1073_javautilEnumerationnextElement'"
                BaseType bt = (BaseType) e.Current;
                String normName = normalize(bt.Name);

                if (topName.Equals(normName))
                    foundIt = true;
            }

            if (!foundIt) {
                // The Attribute referenced is at the top level of the DDS itself.
                // The Attributes at the top level of the DDS get repackaged into
                // a special AttributeTable, this makes the Aliases that point to
                // any of these Attribute resolve correctly.
                prefix = "." + LooseEndsTableName;
            }

            return (prefix + attribute);
        }

        /// <summary> Make A helper function for <code>getLooseEndsTableName</code>
        /// insures that there are no naming conflicts when creating a looseEnds
        /// <code>AttributeTable</code>
        /// 
        /// </summary>
        /// <param name="name">
        /// </param>
        /// <param name="attempt">
        /// </param>
        /// <returns>
        /// 
        /// 
        /// </returns>
        /// <seealso cref="LooseEndsTableName">
        /// </seealso>
        /// <seealso cref="DAS">
        /// </seealso>
        private String checkLooseEndsTableNameConflict(String name, int attempt) {
            IEnumerator e = Variables;
            //UPGRADE_TODO: Method 'java.util.Enumeration.hasMoreElements' was converted to 'System.Collections.IEnumerator.MoveNext' which has a different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1073_javautilEnumerationhasMoreElements'"
            while (e.MoveNext()) {
                //UPGRADE_TODO: Method 'java.util.Enumeration.nextElement' was converted to 'System.Collections.IEnumerator.Current' which has a different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1073_javautilEnumerationnextElement'"
                BaseType bt = (BaseType) e.Current;
                String btName = bt.Name;

                //System.out.println("bt: '"+btName+"'  dataset: '"+name+"'");

                if (btName.Equals(name)) {
                    name = RepairLooseEndsTableConflict(this, name, attempt++);
                    name = checkLooseEndsTableNameConflict(name, attempt);
                }
            }

            AttributeTable at = AttributeTable;
            e = at.Names.GetEnumerator();
            //UPGRADE_TODO: Method 'java.util.Enumeration.hasMoreElements' was converted to 'System.Collections.IEnumerator.MoveNext' which has a different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1073_javautilEnumerationhasMoreElements'"
            while (e.MoveNext()) {
                //UPGRADE_TODO: Method 'java.util.Enumeration.nextElement' was converted to 'System.Collections.IEnumerator.Current' which has a different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1073_javautilEnumerationnextElement'"
                String aName = (String) e.Current;

                if (aName.Equals(name)) {
                    name = RepairLooseEndsTableConflict(this, name, attempt++);
                    name = checkLooseEndsTableNameConflict(name, attempt);
                }
            }
            return (name);
        }

        /// <summary> A helper function for <code>checkLooseEndsTableNameConflict</code>
        /// insures that there are no naming conflicts when creating a looseEnds
        /// <code>AttributeTable</code>
        /// 
        /// </summary>
        /// <param name="badName">
        /// </param>
        /// <param name="attempt">
        /// </param>
        /// <param name="dds"></param>
        /// <returns>
        /// </returns>
        /// <seealso cref="checkLooseEndsTableNameConflict">
        /// </seealso>
        private static String RepairLooseEndsTableConflict(DDS dds, String badName, int attempt) {
            Console.Out.WriteLine("Repairing toplevel attribute table name conflict. Attempt: " + attempt);

            String name = "";

            switch (attempt) {
                case 0:
                    name = badName + "_DatasetAttributes_0";
                    break;

                default:
                    int last_ = badName.LastIndexOf("_");
                    name = badName.Substring(0, (last_) - (0)) + "_" + attempt;
                    break;
            }

            return (name);
        }


        /// <summary> Builds AttributeTables (from BaseType variables) for us in
        /// a DAS created by getDAS()
        /// 
        /// 
        /// </summary>
        /// <param name="bt">
        /// </param>
        /// <param name="atbl">
        /// </param>
        /// <throws>  DASException </throws>
        /// <summary> 
        /// </summary>
        private void buildDASAttributeTable(BaseType bt, AttributeTable atbl) {
            // Get this BaseType's AttributeTable. Since we are using the AttributeTable
            // interface to build the DAS (which will have a different structure than the
            // table we are getting anyway), we don't need a copy, only the reference.
            AttributeTable tBTAT = bt.AttributeTable;

            // Start a new (child) AttributeTable (using the name of the one we are
            // copying) in the (parent) AttributeTable we are working on.
            AttributeTable newAT = atbl.appendContainer(tBTAT.Name);

            Trace.TraceInformation("newAT.getName(): " + newAT.Name);

            // Get each Attribute in the AttributeTable that we are copying,
            // and then put it's values into our new AttributeTable;
            IEnumerator e = tBTAT.Names.GetEnumerator();
            //UPGRADE_TODO: Method 'java.util.Enumeration.hasMoreElements' was converted to 'System.Collections.IEnumerator.MoveNext' which has a different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1073_javautilEnumerationhasMoreElements'"
            while (e.MoveNext()) {
                //UPGRADE_TODO: Method 'java.util.Enumeration.nextElement' was converted to 'System.Collections.IEnumerator.Current' which has a different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1073_javautilEnumerationnextElement'"
                String attrName = (String) e.Current;
                Attribute attr = tBTAT.getAttribute(attrName);
                populateAttributeTable(newAT, attr);
            }

            // If this BaseType is a "container" type (aka complex type, aka DConstructor)
            // Then we have to Search it's children for Attributes and then  them
            // and put them in our new Attribute Table.
            if (bt is DConstructor) {
                IEnumerator v = ((DConstructor) bt).Variables;

                //UPGRADE_TODO: Method 'java.util.Enumeration.hasMoreElements' was converted to 'System.Collections.IEnumerator.MoveNext' which has a different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1073_javautilEnumerationhasMoreElements'"
                while (v.MoveNext()) {
                    //UPGRADE_TODO: Method 'java.util.Enumeration.nextElement' was converted to 'System.Collections.IEnumerator.Current' which has a different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1073_javautilEnumerationnextElement'"
                    BaseType thisBT = (BaseType) v.Current;

                    buildDASAttributeTable(thisBT, newAT);
                }
            }
        }


        /// <summary> Builds AttributeTables (from BaseType variables) for us in
        /// a DAS created by getDAS()
        /// 
        /// </summary>
        /// <param name="atTable">
        /// </param>
        /// <param name="attr">
        /// </param>
        /// <throws>  DASException </throws>
        /// <summary> 
        /// </summary>
        /// <seealso cref="buildDASAttributeTable(BaseType, AttributeTable)">
        /// </seealso>
        private void populateAttributeTable(AttributeTable atTable, Attribute attr) {
            // Always check for Aliases first! They return the values for their targets
            // when asked if they are containers!
            if (attr.isAlias()) {
                String alias = attr.Name;
                String attribute = ((Alias) attr).AliasedToAttributeFieldAsClearString;

                Trace.TraceInformation("Adding Alias name: " + alias);

                atTable.addAlias(alias, convertDDSAliasFieldsToDASAliasFields(attribute));
            }
            else if (attr.isContainer()) {
                // If this Attribute is a container of other Attributes (an AttributeTable)
                // then we need to recurse to get it's children.

                // Get this Attribute's container (AttributeTable).
                // Since we are using the AttributeTable
                // interface to build the DAS (which will have a different structure than the
                // table we are getting anyway), we don't need a copy, only the reference.
                AttributeTable thisTable = attr.getContainer();

                // Start a new (child) AttributeTable (using the name of the one we are
                // copying) in the (parent) AttributeTable we are working on.
                Trace.TraceInformation("Appending AttributeTable name: " + thisTable.Name);
                
                AttributeTable newTable = atTable.appendContainer(thisTable.Name);

                // Get each Attribute in the AttributeTable that we are copying,
                // and then put it's values into our new AttributeTable;
                IEnumerator e = thisTable.Names.GetEnumerator();
                //UPGRADE_TODO: Method 'java.util.Enumeration.hasMoreElements' was converted to 'System.Collections.IEnumerator.MoveNext' which has a different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1073_javautilEnumerationhasMoreElements'"
                while (e.MoveNext()) {
                    //UPGRADE_TODO: Method 'java.util.Enumeration.nextElement' was converted to 'System.Collections.IEnumerator.Current' which has a different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1073_javautilEnumerationnextElement'"
                    String attrName = (String) e.Current;
                    Attribute thisAttr = thisTable.getAttribute(attrName);
                    populateAttributeTable(newTable, thisAttr);
                }
            }
            else {
                // Since the Attribute is a "leaf" and not a container we need to
                // push it's contents into the AttributeTable that we are building.
                int type = attr.Type;
                String name = attr.Name;
                IEnumerator v = attr.Values;
                //UPGRADE_TODO: Method 'java.util.Enumeration.hasMoreElements' was converted to 'System.Collections.IEnumerator.MoveNext' which has a different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1073_javautilEnumerationhasMoreElements'"
                while (v.MoveNext()) {
                    //UPGRADE_TODO: Method 'java.util.Enumeration.nextElement' was converted to 'System.Collections.IEnumerator.Current' which has a different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1073_javautilEnumerationnextElement'"
                    String value_Renamed = (String) v.Current;

                    Trace.TraceInformation("AtributeTable: " + atTable.Name + " Appending Attribute name: " + name +
                                              "  type: " + type + " value: " + value_Renamed);
                    
                    atTable.appendAttribute(name, type, value_Renamed);
                }
            }
        }


        /// <summary> Print a DAS constructed from this DDS and it's BaseType variables.
        /// 
        /// </summary>
        /// <param name="os">The <code>OutputStream</code> to Print to.
        /// </param>
        public virtual void printDAS(Stream os) {
            //UPGRADE_WARNING: At least one expression was used more than once in the target code. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1181'"
            StreamWriter pw =
                new StreamWriter(
                    new StreamWriter(new StreamWriter(os, Encoding.Default).BaseStream,
                                     new StreamWriter(os, Encoding.Default).Encoding).BaseStream,
                    new StreamWriter(new StreamWriter(os, Encoding.Default).BaseStream,
                                     new StreamWriter(os, Encoding.Default).Encoding).Encoding);
            printDAS(pw);
            pw.Flush();
        }


        /// <summary> Print a DAS constructed from this DDS and it's BaseType variables.
        /// 
        /// </summary>
        /// <param name="pw">The <code>StreamWriter</code> to Print to.
        /// </param>
        public virtual void printDAS(StreamWriter pw) {
            try {
                DAS myDAS;
                myDAS = this.DAS;
                myDAS.print(pw);
            }
            catch (DASException dasE) {
                //UPGRADE_TODO: Method 'java.io.StreamWriter.println' was converted to 'System.IO.TextWriter.WriteLine' which has a different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1073_javaioStreamWriterprintln_javalangString'"
                //UPGRADE_TODO: The equivalent in .NET for method 'java.lang.Throwable.getMessage' may return a different value. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1043'"
                pw.WriteLine("\n\nCould not get a DAS object to Print!\n" +
                             "DDS.getDAS() threw an Exception. Message: \n" + dasE.Message);
            }
        }


        /// <summary> Removes a variable from the <code>DDS</code>.
        /// Does nothing if the variable can't be found.
        /// If there are multiple variables with the same name, only the first
        /// will be removed.  To detect this, call the <code>CheckSemantics</code>
        /// method to verify that each variable has a unique name.
        /// 
        /// </summary>
        /// <param name="name">the name of the variable to remove.
        /// </param>
        /// <seealso cref="CheckSemantics">
        /// </seealso>
        public virtual void delVariable(String name) {
            try {
                BaseType bt = getVariable(name);
                vars.Remove(bt);
            }
            catch (NoSuchVariableException) {}
        }

        /// <summary> Is the variable <code>var</code> a vector of DConstructors? Return
        /// true if it is, false otherwise. This mess will recurse into a
        /// DVector's template BaseType (which is a BaseTypePrimivitiveVector) and
        /// look to see if that is either a DConstructor or <em>contains</em> a
        /// DConstructor. So the <code>List Strucutre { ... } g[10];</code> should
        /// be handled correctly. <p>
        /// <p/>
        /// Note that the List type modifier may only appear once.
        /// </summary>
        private static DConstructor isVectorOfDConstructor(BaseType var) {
            if (!(var is DVector))
                return null;
            if (!(((DVector) var).PrimitiveVector is BaseTypePrimitiveVector))
                return null;
            // OK. We have a DVector whose template is a BaseTypePrimitiveVector.
            BaseTypePrimitiveVector btpv = (BaseTypePrimitiveVector) ((DVector) var).PrimitiveVector;
            // After that nasty cast, is the template a DConstructor?
            if (btpv.Template is DConstructor)
                return (DConstructor) btpv.Template;
            else
                return isVectorOfDConstructor(btpv.Template);
        }

        /// <summary> Returns a reference to the named variable.
        /// 
        /// </summary>
        /// <param name="name">the name of the variable to return.
        /// </param>
        /// <returns> the variable named <code>name</code>.
        /// </returns>
        /// <throws>  NoSuchVariableException if the variable isn't found. </throws>
        public override BaseType getVariable(String name) {
            ArrayList s = new ArrayList();
            s = Search(name, s);
            return (BaseType) SupportClass.StackSupport.Pop(s);
        }

        /// <summary> Adds a variable to the container. This overrides the
        /// getVariable() in DStructure in order to keep the
        /// parent value from getting set. Otherwise the
        /// name of the DDS (which is typically the name of the Dataset)
        /// will appear in calls to BaseType.getLongName().
        /// <h2>
        /// This might be a mistake!!! Watch out for bugs induced by this
        /// method.
        /// </h2>
        /// 
        /// </summary>
        /// <param name="v">   the variable to add.
        /// </param>
        /// <param name="part">ignored for <code>DSequence</code>.
        /// </param>
        public override void addVariable(BaseType v, int part) {
            // v.setParent(this);
            vars.Add(v);
        }

        /// <summary> Look for <code>name</code> in the DDS. Start the Search using the
        /// ctor variable (or array/list of ctors) found on the top of the Stack
        /// <code>compStack</code> (for component stack). When the named variable
        /// is found, return the stack compStack modified so that it now contains
        /// each ctor-type variable that on the path to the named variable. If the
        /// variable is not found after exhausting all possibilities, throw
        /// NoSuchVariable.<p>
        /// <p/>
        /// Note: This method takes the stack as a parameter so that it can be
        /// used by a parser that is working through a list of identifiers that
        /// represents the path to a variable <em>as well as</em> a shorthand
        /// notation for the identifier that is the equivalent to the leaf node
        /// name alone. In the form case the caller helps build the stack by
        /// repeatedly calling <code>Search</code>, in the latter case this method
        /// must build the stack itself. This method is over kill for the first
        /// case.
        /// 
        /// </summary>
        /// <param name="name">     Search for the named variable.
        /// </param>
        /// <param name="compStack">The component stack. This holds the BaseType variables
        /// that match the each component of a specific variable's name. This
        /// method starts its Search using the element at the top of the stack and
        /// adds to the stack. The order of BaseType variables on the stack is the
        /// reverse of the tree-traverse order. That is, the top most element on
        /// the stack is the BaseType for the named variable, <em>under</em> that
        /// is the named variable's parent and so on.
        /// </param>
        /// <returns> A stack of BaseType variables which hold the path from the top
        /// of the DDS to the named variable.
        /// </returns>
        /// <throws>  NoSuchVariableException </throws>
        public virtual ArrayList Search(String name, ArrayList compStack) {
            DDSSearch ddsSearch = new DDSSearch(this, compStack);

            if (ddsSearch.deepSearch(name))
                return ddsSearch.components;
            else
                throw new NoSuchVariableException("The variable `" + name + "' was not found in the dataset.");
        }

        //UPGRADE_NOTE: Field 'EnclosingInstance' was added to class 'DDSSearch' to access its enclosing instance. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1019'"
        /// <summary> Find variables in the DDS when users name them with either fully- or
        /// partially-qualified names.
        /// </summary>
        private sealed class DDSSearch
        {
            private void InitBlock(DDS penclosingInstance) {
                this.enclosingInstance = penclosingInstance;
            }

            private DDS enclosingInstance;

            public DDS Enclosing_Instance {
                get { return enclosingInstance; }
            }

            internal ArrayList components;

            internal DDSSearch(DDS enclosingInstance, ArrayList c) {
                InitBlock(enclosingInstance);
                components = c;
            }

            internal BaseType simpleSearch(String name, BaseType start) {
                IEnumerator e;
                DConstructor dcv;
                if (start == null)
                    e = Enclosing_Instance.Variables;
                    // Start with the whole DDS
                else if (start is DConstructor)
                    e = ((DConstructor) start).Variables;
                else if ((dcv = isVectorOfDConstructor(start)) != null)
                    e = dcv.Variables;
                else
                    return null;

                //UPGRADE_TODO: Method 'java.util.Enumeration.hasMoreElements' was converted to 'System.Collections.IEnumerator.MoveNext' which has a different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1073_javautilEnumerationhasMoreElements'"
                while (e.MoveNext()) {
                    //UPGRADE_TODO: Method 'java.util.Enumeration.nextElement' was converted to 'System.Collections.IEnumerator.Current' which has a different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1073_javautilEnumerationnextElement'"
                    BaseType v = (BaseType) e.Current;
                    if (v.Name.Equals(name)) {
                        return v;
                    }
                }

                return null; // Not found
            }

            /// <summary> Look for the variable named <code>name</code>. First perform the
            /// shallow Search (see simpleSearch) and then look through all the
            /// ctor variables. If there are no more ctors to check and the
            /// variable has not been found, return false.
            /// <p/>
            /// Note that this method uses the return value to indicate whether a
            /// particular invocation found <code>name</code>.
            /// </summary>
            internal bool deepSearch(String name) {
                BaseType start = (components.Count == 0) ? null : (BaseType) components[components.Count - 1];

                BaseType found;

                if ((found = simpleSearch(name, start)) != null) {
                    components.Add(found);
                    return true;
                }

                IEnumerator e;
                DConstructor dcv;
                if (start == null)
                    e = Enclosing_Instance.Variables;
                    // Start with the whole DDS
                else if (start is DConstructor)
                    e = ((DConstructor) start).Variables;
                else if ((dcv = isVectorOfDConstructor(start)) != null)
                    e = dcv.Variables;
                else
                    return false;

                //UPGRADE_TODO: Method 'java.util.Enumeration.hasMoreElements' was converted to 'System.Collections.IEnumerator.MoveNext' which has a different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1073_javautilEnumerationhasMoreElements'"
                while (e.MoveNext()) {
                    //UPGRADE_TODO: Method 'java.util.Enumeration.nextElement' was converted to 'System.Collections.IEnumerator.Current' which has a different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1073_javautilEnumerationnextElement'"
                    BaseType v = (BaseType) e.Current;
                    components.Add(v);
                    if (deepSearch(name))
                        return true;
                    else
                        SupportClass.StackSupport.Pop(components);
                }

                // This second return takes care of the case where a dataset
                // lists a bunch of ctor variable, one after another. Once the
                // first ctor (say a Grid) has been searched returning false to
                // the superior invocation of deepSearch pops it off the stack
                // and the while loop will Search starting with the next variable
                // in the DDS.
                return false;
            }
        }

        /// <summary> Returns the number of variables in the dataset.
        /// 
        /// </summary>
        /// <returns> the number of variables in the dataset.
        /// </returns>
        public int numVariables() {
            return vars.Count;
        }

        /// <summary> Reads a <code>DDS</code> from the named <code>InputStream</code>. This
        /// method calls a generated parser to interpret an ASCII representation of a
        /// <code>DDS</code>, and regenerate that <code>DDS</code> in memory.
        /// This method does the following:
        /// <ul>
        /// <li> Gets a new <code>DDSParser</code> using the <code>BaseTypeFactory</code>
        /// held in this (the <code>DDS</code>) class. </li>
        /// <li> Uses the <code>DDSParser</code> to parse the DDS waiting
        /// in the <code>InputStream</code> <i>is</i>. </li>
        /// </ul>
        /// <p/>
        /// This method does <b>NOT</b> need to call <code>DDS.CheckForAttributeNameConflict()</code>
        /// or <code>DDS.resolveAliases()</code> as the syntax of the DDS
        /// does not support the inclusion of <code>Attribute</code> or
        /// <code>Alias</code> members.
        /// 
        /// </summary>
        /// <param name="is_Renamed">the InputStream containing the <code>DDS</code> to parse.
        /// </param>
        /// <throws>  ParseException thrown on a parser error. </throws>
        /// <throws>  DDSException   thrown on an error constructing the </throws>
        /// <summary>                        <code>DDS</code>.
        /// </summary>
        /// <seealso cref="NDODS.DAP.Parser.DDSParser">
        /// </seealso>
        /// <seealso cref="DDSXMLParser">
        /// </seealso>
        public virtual void parse(BinaryReader is_Renamed) {
            DDSParser dp = new DDSParser(is_Renamed);

            dp.Dataset(this, factory);
        }


        /// <summary> Reads a <b>DDX</b> from the named <code>InputStream</code>. This
        /// method calls a generated parser to interpret an XML representation of a
        /// <code>DDS</code> (aka a <b>DDX</b>), and instantiate that
        /// <code>DDS</code> in memory. This method does the following:
        /// <ul>
        /// <li> Gets a new <code>DDSXMLParser</code> using the <code>BaseTypeFactory</code>
        /// held in this (the <code>DDS</code>) class. </li>
        /// <li> Uses the <code>DDSXMLParser</code> to parse the DDX waiting
        /// in the <code>InputStream</code> <i>is</i>. </li>
        /// <li> Calls <code>DDS.CheckForAttributeNameConflict()</code></li>
        /// <li> Calls <code>DDS.resolveAliases()</code></li>
        /// </ul>
        /// <p/>
        /// The last two items should be called EVERY time a <code>DDS</code>
        /// is populated with variables ( by a parser, or through the <code>DDS</code> API)
        /// and prior to releasing it for use to any calling program.
        /// 
        /// </summary>
        /// <param name="is_Renamed">        the InputStream containing the <code>DDS</code> to parse.
        /// </param>
        /// <param name="validation">Is a bool indicating whether or not the parser should
        /// validate the XML document using the Schema (typically referenced in the
        /// document itself). In general server side applications should always vaidate,
        /// while clients shouldn't bother (since they are ostensibly receiving the
        /// document from a server that has already done so.)
        /// </param>
        /// <throws>  DDSException thrown on an error constructing the </throws>
        /// <summary>                      <code>DDS</code>.
        /// </summary>
        /// <seealso cref="DDSXMLParser">
        /// </seealso>
        /// <seealso cref="CheckForAttributeNameConflict">
        /// </seealso>
        /// <seealso cref="resolveAliases">
        /// </seealso>
        /// <opendap.ddx.experimental>  </opendap.ddx.experimental>
        public virtual void parseXML(Stream is_Renamed, bool validation) {
            DDSXMLParser dp = new DDSXMLParser(opendapNameSpace);

            dp.parse(is_Renamed, this, factory, validation);

            // Check for name conflicts. IN the XML representation
            // of the DDS it is syntactically possible for a
            // variable container (Dconstructor) to possess an
            // Attribute that has the same name as one of the container
            // variable's member variables. That's a NO-NO!.
            // Check for it here and throw a nice fat exception if we find it.

            CheckForAttributeNameConflict();

            // Resolve the aliases. Aliases are basically analagous
            // to softlinks in a UNIX filesystem. Since an alias
            // can point any Attribute in the dataset, the vailidity
            // of the alias cannot be checked until all of the
            // members of the Dataset (both variables and their
            // Attributes) have been built. Once that is done
            // we can check to make sure that every alias points
            // at a vaild Attribute (and not another alias, non-existent
            // Attribute, etc)

            resolveAliases();
        }


        /// <summary> Reads a <b>DDX</b> from the named <code>Document</code>. This
        /// method calls a generated parser to interpret an XML representation of a
        /// <code>DDS</code> (aka a <b>DDX</b>), and instantiate that
        /// <code>DDS</code> in memory. This method does the following:
        /// <ul>
        /// <li> Gets a new <code>DDSXMLParser</code> using the <code>BaseTypeFactory</code>
        /// held in this (the <code>DDS</code>) class. </li>
        /// <li> Uses the <code>DDSXMLParser</code> to parse the DDX waiting
        /// in the <code>InputStream</code> <i>is</i>. </li>
        /// <li> Calls <code>DDS.CheckForAttributeNameConflict()</code></li>
        /// <li> Calls <code>DDS.resolveAliases()</code></li>
        /// </ul>
        /// 
        /// <p/>
        /// The last two items should be called EVERY time a <code>DDS</code>
        /// is populated with variables ( by a parser, or through the <code>DDS</code> API)
        /// and prior to releasing it for use to any calling program.
        /// 
        /// </summary>
        /// <param name="ddxDoc">    A JDOM Document containing the <code>DDS</code> to parse.
        /// </param>
        /// <param name="validation">Is a bool indicating whether or not the parser should
        /// validate the XML document using the Schema (typically referenced in the
        /// document itself). In general server side applications should always vaidate,
        /// while clients shouldn't bother (since they are ostensibly receiving the
        /// document from a server that has already done so.)
        /// </param>
        /// <throws>  DDSException thrown on an error constructing the </throws>
        /// <summary>                      <code>DDS</code>.
        /// </summary>
        /// <seealso cref="DDSXMLParser">
        /// </seealso>
        /// <seealso cref="CheckForAttributeNameConflict">
        /// </seealso>
        /// <seealso cref="resolveAliases">
        /// </seealso>
        /// <opendap.ddx.experimental>  </opendap.ddx.experimental>
        public virtual void parseXML(XmlDocument ddxDoc, bool validation) {
            DDSXMLParser dp = new DDSXMLParser(opendapNameSpace);

            dp.parse(ddxDoc, this, factory, validation);

            // Check for name conflicts. IN the XML representation
            // of the DDS it is syntactically possible for a
            // variable container (Dconstructor) to possess an
            // Attribute that has the same name as one of the container
            // variable's member variables. That's a NO-NO!.
            // Check for it here and throw a nice fat exception if we find it.

            CheckForAttributeNameConflict();

            // Resolve the aliases. Aliases are basically analagous
            // to softlinks in a UNIX filesystem. Since an alias
            // can point any Attribute in the dataset, the vailidity
            // of the alias cannot be checked until all of the
            // members of the Dataset (both variables and their
            // Attributes) have been built. Once that is done
            // we can check to make sure that every alias points
            // at a vaild Attribute (and not another alias, non-existent
            // Attribute, etc)

            resolveAliases();
        }


        /// <summary> Check the semantics of the <code>DDS</code>. If
        /// <code>all</code> is true, check not only the semantics of the
        /// <code>DDS</code> itself, but also recursively check all variables
        /// in the dataset.
        /// 
        /// </summary>
        /// <param name="all">this flag indicates whether to check the semantics of the
        /// member variables, too.
        /// </param>
        /// <throws>  BadSemanticsException if semantics are bad </throws>
        public override void CheckSemantics(bool all) {
            if (Name == null) {
                Console.Error.WriteLine("A dataset must have a name");
                throw new BadSemanticsException("DDS.CheckSemantics(): A dataset must have a name");
            }
            Utilities.UniqueNames(vars, Name, "Dataset");

            if (all) {
                //UPGRADE_TODO: Method 'java.util.Enumeration.hasMoreElements' was converted to 'System.Collections.IEnumerator.MoveNext' which has a different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1073_javautilEnumerationhasMoreElements'"
                for (IEnumerator e = vars.GetEnumerator(); e.MoveNext();) {
                    //UPGRADE_TODO: Method 'java.util.Enumeration.nextElement' was converted to 'System.Collections.IEnumerator.Current' which has a different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1073_javautilEnumerationnextElement'"
                    BaseType bt = (BaseType) e.Current;
                    bt.CheckSemantics(true);
                }
            }
        }


        /// <summary> Print the <code>DDS</code> on the given <code>StreamWriter</code>.
        /// 
        /// </summary>
        /// <param name="os">the <code>StreamWriter</code> to use for output.
        /// </param>
        public virtual void Print(StreamWriter os) {
            //UPGRADE_TODO: Method 'java.io.StreamWriter.println' was converted to 'System.IO.TextWriter.WriteLine' which has a different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1073_javaioStreamWriterprintln_javalangString'"
            os.WriteLine("Dataset {");
            //UPGRADE_TODO: Method 'java.util.Enumeration.hasMoreElements' was converted to 'System.Collections.IEnumerator.MoveNext' which has a different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1073_javautilEnumerationhasMoreElements'"
            for (IEnumerator e = vars.GetEnumerator(); e.MoveNext();) {
                //UPGRADE_TODO: Method 'java.util.Enumeration.nextElement' was converted to 'System.Collections.IEnumerator.Current' which has a different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1073_javautilEnumerationnextElement'"
                BaseType bt = (BaseType) e.Current;


                bt.PrintDeclaration(os);
            }
            os.Write("} ");
            if (Name != null)
                os.Write(Name);
            //UPGRADE_TODO: Method 'java.io.StreamWriter.println' was converted to 'System.IO.TextWriter.WriteLine' which has a different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1073_javaioStreamWriterprintln_javalangString'"
            os.WriteLine(";");
        }

        /// <summary> Print the <code>DDS</code> on the given <code>OutputStream</code>.
        /// 
        /// </summary>
        /// <param name="os">the <code>OutputStream</code> to use for output.
        /// </param>
        /// <seealso cref="Print(StreamWriter)">
        /// </seealso>
        public void Print(Stream os) {
            //UPGRADE_WARNING: At least one expression was used more than once in the target code. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1181'"
            StreamWriter pw = new StreamWriter(os, Encoding.Default);
            Print(pw);
            pw.Flush();
        }


        /// <summary> Before the DDS can be used all of the Aliases in the various
        /// AttributeTables must be resolved. This means that it is necessary to verify that
        /// each Alias references an Attribute that exists, and is not another Alias. This
        /// is accomplished by searching the DDS's variable's attribute holdings for Aliases
        /// Everytime an Alias is located, a new Search begins to find the Attribute that the
        /// Alias is attemoting to reference.
        /// <p/>
        /// This method recursively searchs through the passed <code>BaseType</code> parameter
        /// bt for Alias members of AttributeTables, and when they are found attempts to
        /// resolve them to a specific Attribute.
        /// <p/>
        /// This method should be called ONLY after the entire
        /// DDS has been parsed and /or built using the DDS API.
        /// <h2>
        /// This method should/must always be called prior to using a DDS!
        /// </h2>
        /// This method manipulates the global (private) variable <code>currentBT</code>.
        /// This method manipulates the global (private) variable <code>currentAT</code>.
        /// </summary>
        public virtual void resolveAliases() {
            currentBT = null;
            currentAT = null;
            resolveAliases(this);
        }


        /// <summary> Before the DDS can be used all of the Aliases in the various
        /// AttributeTables must be resolved. This means that it is necessary to verify that
        /// each Alias references an Attribute that exists, and is not another Alias. This
        /// is accomplished by searching the DDS's variable's attribute holdings for Aliases
        /// Everytime an Alias is located, a new Search begins to find the Attribute that the
        /// Alias is attempting to reference.
        /// <p/>
        /// This method recursively searchs through the passed <code>BaseType</code> parameter
        /// bt for Alias members of AttributeTables, and when they are found attempts to
        /// resolve them to a specific Attribute.
        /// <p/>
        /// This method gets called at the top level at the parser ONLY after the entire
        /// DDS has been parsed and built. It's intial invocation get passed the DDS (which
        /// is in fact a <code>BaseType</code>)
        /// <p/>
        /// <p/>
        /// This method manipulates the global variable <code>currentBT</code>.
        /// 
        /// </summary>
        /// <param name="bt">The <code>BaseType</code> in which to Search for and resolve Alias members
        /// </param>
        private void resolveAliases(BaseType bt) {
            // cache the current/parent BaseType (a container)
            BaseType cacheBT = currentBT;

            // Make the one we are about to Search the current one.
            currentBT = bt;

            // Make the current AttributeTable null to indicate that we are at the top
            // AttributeTable of a new current BaseType.
            currentAT = null;


            if (Debug.isSet("DDS.resolveAliases"))
                Console.Out.WriteLine("Searching for Aliases in the Attributes of Variable: " + bt.Name);

            // Process the Attributes of this BaseType.
            resolveAliases(bt.AttributeTable);

            // Now if this current BaseType is a container type, then we better
            // Search and resolve Aliases in it's children.
            if (bt is DConstructor) {
                if (Debug.isSet("DDS.resolveAliases"))
                    Console.Out.WriteLine("Searching for Aliases in the children of Variable: " + bt.Name);

                IEnumerator bte = ((DConstructor) bt).Variables;

                //UPGRADE_TODO: Method 'java.util.Enumeration.hasMoreElements' was converted to 'System.Collections.IEnumerator.MoveNext' which has a different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1073_javautilEnumerationhasMoreElements'"
                while (bte.MoveNext()) {
                    //UPGRADE_TODO: Method 'java.util.Enumeration.nextElement' was converted to 'System.Collections.IEnumerator.Current' which has a different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1073_javautilEnumerationnextElement'"
                    BaseType thisBT = (BaseType) bte.Current;

                    // Recursive call...
                    resolveAliases(thisBT);
                }
            }

            // Restore the previous current BaseType state.
            currentBT = cacheBT;
        }


        /// <summary> This method recursively searchs through the passed <code>AttributeTable</code> parameter
        /// at for Alias members. When an Alias is found the method attempts to
        /// resolve it to a specific Attribute.
        /// <p/>
        /// This method is invoked by <code>resolveAliases(BaseType bt)</code>, and is
        /// used to Search for Aliases in AttributeTables found in a BaseTypes Attributes.
        /// <p/>
        /// This method manipulates the global variable <code>currentBT</code>.
        /// 
        /// </summary>
        /// <param name="at">The <code>AttributeTable</code> in which to Search for and resolve Alias members
        /// </param>
        private void resolveAliases(AttributeTable at) {
            // Cache the current (parent) Attribute table. This value is
            // null if this method is call from resolveAliases(BasetType bt)
            AttributeTable cacheAT = currentAT;

            // Set the current AttributeTable to the one that we are searching.
            currentAT = at;

            //getall of the Attributes from the table.
            IEnumerator aNames = currentAT.Names.GetEnumerator();
            //UPGRADE_TODO: Method 'java.util.Enumeration.hasMoreElements' was converted to 'System.Collections.IEnumerator.MoveNext' which has a different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1073_javautilEnumerationhasMoreElements'"
            while (aNames.MoveNext()) {
                //UPGRADE_TODO: Method 'java.util.Enumeration.nextElement' was converted to 'System.Collections.IEnumerator.Current' which has a different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1073_javautilEnumerationnextElement'"
                String aName = (String) aNames.Current;
                Attribute thisA = currentAT.getAttribute(aName);

                if (thisA.isAlias()) {
                    //Is Alias? Resolve it!
                    resolveAlias((Alias) thisA);
                    if (Debug.isSet("DDS.resolveAliases"))
                        Console.Out.WriteLine("Resolved Alias: '" + thisA.Name + "'\n");
                }
                else if (thisA.isContainer()) {
                    //Is AttributeTable (container)? Search it!
                    resolveAliases(thisA.getContainer());
                }
            }

            // Restore the previous currentAT state.
            currentAT = cacheAT;
        }


        /// <summary> This method attempts to resolve the past Alias to a specific Attribute in the DDS.
        /// It does this by:
        /// <ul>
        /// <li>1) Tokenizing the Alias's attribute field (see <code>Alias</code>) </li>
        /// <li>2) Evaluating the tokenized field to locate the longest
        /// possible variable name represented as a consecutive set of tokens </li>
        /// <li>2) Evaluating the the remaining tokenized field to locate the Attribute
        /// that this Alias is attempting to reference</li>
        /// <li>4) Setting the Aliases internal references for it's Variable and it's Attribute.
        /// </ul>
        /// <p/>
        /// If an Attribute matching the definition of the Alias cannot be located,
        /// an Exception is thrown
        /// 
        /// </summary>
        /// <param name="alias">The <code>Alias</code> which needs to be resolved
        /// </param>
        private void resolveAlias(Alias alias) {
            //Get the crucial stuff out of the Alias
            String name = alias.Name;
            String attribute = alias.AliasedToAttributeFieldAsClearString;

            if (Debug.isSet("DDS.resolveAliases"))
                Console.Out.WriteLine("\n\nFound: Alias " + name + "  " + attribute);

            // The Attribute field MAY NOT be empty.
            if (attribute.Equals("")) {
                throw new MalformedAliasException("The attribute 'attribute' in the Alias " + "element (name: '" + name +
                                                  "') must have a value other than an empty string.");
            }


            if (Debug.isSet("DDS.resolveAliases"))
                Console.Out.WriteLine("Attribute: `" + attribute + "'");

            // Tokenize the attribute field.
            ArrayList aNames = tokenizeAliasField(attribute);

            if (Debug.isSet("DDS.resolveAliases")) {
                Console.Out.WriteLine("Attribute name tokenized to " + aNames.Count + " elements");
                IEnumerator e = aNames.GetEnumerator();
                //UPGRADE_TODO: Method 'java.util.Enumeration.hasMoreElements' was converted to 'System.Collections.IEnumerator.MoveNext' which has a different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1073_javautilEnumerationhasMoreElements'"
                while (e.MoveNext()) {
                    //UPGRADE_TODO: Method 'java.util.Enumeration.nextElement' was converted to 'System.Collections.IEnumerator.Current' which has a different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1073_javautilEnumerationnextElement'"
                    String aname = (String) e.Current;
                    Console.Out.WriteLine("name: " + aname);
                }
            }

            // The variable reference is the first part of the attribute field.
            // Let's go find it...


            BaseType targetBT;

            // Absolute paths for attributes names must start with the dot character.
            bool isAbsolutePath = aNames[0].Equals(".");

            if (!isAbsolutePath) {
                //Is it not an absolute path?
                throw new MalformedAliasException("In the Alias '" + name + "'" +
                                                  " the value of the attribute 'attribute' does not begin with the character dot (.). " +
                                                  "The value of the 'attribute' field must always be an absolute path name from the " +
                                                  "top level of the variable reference, and thus must always begin with the dot (.) character.");
            }

            if (aNames.Count == 1) {
                // Is it only a dot?
                throw new MalformedAliasException("In the Alias '" + name + "'" +
                                                  " the value of the attribute 'attribute' contains only the character dot (.). " +
                                                  "The value of the 'attribute' field must always reference an Attribute using an absolute path name from the " +
                                                  "top level of the DAS, and must reference an attribute within the DAS. A simple dot is not allowed.");
            }

            aNames.RemoveAt(0); // Remove the first token, which by now we know is a single dot.


            targetBT = GetDeepestMatchingVariable(this, aNames);

            if (targetBT == null) {
                // No matching BaseType?

                // Then assume the attribute field references a
                // top (Dataset) level Attribute.
                targetBT = this;
            }

            //System.out.println("Alias references variable:	."+targetBT.getLongName());

            // Now that we have found a target BaseType variable that matches the reference in
            // the variable field of the Alias (b.t.w. that's a good thing) let's go
            // see if we can find an Attribute within that targetBT that matches the attribute field
            // in the Alias decleration.

            Attribute targetAT;

            if (aNames.Count == 0) {
                // If there are no remaining tokens in the attribute field then
                // we are referencing the attribute container of the targetBT.
                targetAT = targetBT.GetAttribute();
            }
            else {
                // Go try to find the Attribute in the targetBT.
                targetAT = GetAttribute(targetBT.AttributeTable, aNames);
            }

            alias.MyVariable = targetBT;
            alias.setMyAttribute(targetAT);
        }


        /// <summary> This method executes a (recursive) Search of the <code>AttributeTable</code>
        /// parameter <b>at</b> for an <code>Attribute</code> whose name resolves to
        /// the vector of names contained in the <code>Vector</code> parameter
        /// <b>aNames</b>. An Attribute is considered a match if each of it's node
        /// names in the hierarchy of AttributeTables contained in the
        /// one passed as parameter <b>at</b> matches (equals) the corresponding name
        /// in the Vector <b>aNames</b>.
        /// 
        /// </summary>
        /// <param name="at">    The <code>AttributeTable</code> to Search
        /// </param>
        /// <param name="aNames">The <code>Vector</code> of names to match to the nodes of <b>at</b>
        /// </param>
        /// <opendap.ddx.experimental>  </opendap.ddx.experimental>
        private static Attribute GetAttribute(AttributeTable at, ArrayList aNames) {
            // Get the first node name form the vector.
            String aName = (String) aNames[0];

            // Get the list of child nodes from the AttributeTable
            IEnumerator e = at.Names.GetEnumerator();
            //UPGRADE_TODO: Method 'java.util.Enumeration.hasMoreElements' was converted to 'System.Collections.IEnumerator.MoveNext' which has a different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1073_javautilEnumerationhasMoreElements'"
            while (e.MoveNext()) {
                // Get an Attribute
                //UPGRADE_TODO: Method 'java.util.Enumeration.nextElement' was converted to 'System.Collections.IEnumerator.Current' which has a different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1073_javautilEnumerationnextElement'"
                String atName = (String) e.Current;
                Attribute a = at.getAttribute(atName);

                // Get the Attributes name and Normalize it.
                String normName = normalize(a.Name);

                // Are they the same?
                if (normName.Equals(aName)) {
                    // Make sure this reference doesn't pass through an Alias.
                    if (a.isAlias()) {
                        throw new MalformedAliasException("Aliases may NOT point to other aliases");
                    }

                    //dump the name from the list of names.
                    aNames.RemoveAt(0);

                    // Are there more?
                    if (aNames.Count == 0) {
                        //No! We found it!
                        return (a);
                    }
                    else if (a.isContainer()) {
                        // Is this Attribute a container (it better be)

                        try {
                            // Recursively Search for the rest of the name vector in the container.
                            return (GetAttribute(a.getContainer(), aNames));
                        }
                        catch (NoSuchAttributeException) {
                            throw new MalformedAliasException("Attribute " + a.Name +
                                                              " is not an attribute container. (AttributeTable) " +
                                                              " It may not contain the attribute: " + aName);
                        }
                    }
                    else {
                        // Dead-end, through an exception!

                        throw new MalformedAliasException("Attribute " + a.Name +
                                                          " is not an attribute container. (AttributeTable) " +
                                                          " It may not contain the attribute: " + aName);
                    }
                }
            }
            // Nothing Matched, so this Search failed.
            throw new UnresolvedAliasException("The alias `" + "` references the attribute: `" + aName +
                                               "` which cannot be found.");
        }


        /// <summary> This method executes a (recursive) Search of the <code>DConstructor</code>
        /// parameter <b>dcBT</b> for a <code>BaseType</code> variable whose name resolves to
        /// the vector of names contained in the <code>Vector</code> parameter
        /// <b>vNames</b>. A variable is considered a match if each of it's node
        /// names in the hierarchy of containers in the
        /// one passed as parameter <b>dcBT</b> matches (equals) the corresponding name
        /// in the Vector <b>vNames</b>.
        /// 
        /// </summary>
        /// <param name="dcBT">  The <code>DConstructor</code> to Search
        /// </param>
        /// <param name="vNames">The <code>Vector</code> of names to match to the nodes of <b>at</b>
        /// </param>
        private static BaseType GetDeepestMatchingVariable(DConstructor dcBT, ArrayList vNames) {
            // Get the first name from the Vector
            String vName = (String) vNames[0];

            // Get all of the child variables from the Dconstructor
            IEnumerator bte = dcBT.Variables;
            //UPGRADE_TODO: Method 'java.util.Enumeration.hasMoreElements' was converted to 'System.Collections.IEnumerator.MoveNext' which has a different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1073_javautilEnumerationhasMoreElements'"
            while (bte.MoveNext()) {
                // Get this variable
                //UPGRADE_TODO: Method 'java.util.Enumeration.nextElement' was converted to 'System.Collections.IEnumerator.Current' which has a different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1073_javautilEnumerationnextElement'"
                BaseType bt = (BaseType) bte.Current;

                // Get and normalize it's name.
                String normName = normalize(bt.ClearName);

                // Compare the names
                if (normName.Equals(vName)) {
                    // They match!

                    // Remove the name from the vector.
                    vNames.RemoveAt(0);


                    if (vNames.Count == 0) {
                        // are there more names?
                        // Nope! We Found it!
                        return bt;
                    }

                    if (bt is DConstructor) {
                        // If there are more names then this thing better be a container
                        // recursively Search it for the remaining names...
                        BaseType nextBT = GetDeepestMatchingVariable((DConstructor) bt, vNames);

                        if (nextBT != null)
                            return (nextBT);

                        return (bt);
                    }

                    return (bt);
                }
            }
            return (null);
        }


        /// <summary> The <code>normalize</code> method is used to normalize variable and
        /// attribute name strings prior
        /// to their comparison with the normalized tokens extracted from the
        /// variable and name fields in an Alias declaration.
        /// <p/>
        /// The rule for this normalization is as follows:
        /// <p/>
        /// <ul>
        /// <li> The " (double quote) and the \ (backslash, aka escape)
        /// characters MUST be escaped (using the \ character) in the <b>variable</b>
        /// and <b>attribute</b> fields.</li>
        /// </ul>
        /// 
        /// </summary>
        /// <param name="field">The string to be normalized.
        /// </param>
        /// <returns> The "normalized" string.
        /// </returns>
        public static String normalize(String field) {
            StringBuilder sb = new StringBuilder(field);

            for (int offset = 0; offset < sb.Length; offset++) {
                char c = sb[offset];

                // for every quote and slach in the string, add a slash in front of it.
                if (c == slash || c == quote) {
                    sb.Insert(offset, slash);
                    offset++;
                }
            }

            Trace.TraceInformation("String: `" + field + "` normalized to: `" + sb + "`");

            return (sb.ToString());
        }


        /// <summary> The <code>tokenizeAliasFiled()</code> method is used to tokenize
        /// the <b>variable</b> and the <b>attribute</b> fields in the alias
        /// declaration. It is required that these fields be <b>normalized</b>
        /// in the XML instance document. The rules for this normalization
        /// are as follows:
        /// <ul>
        /// <p/>
        /// <li> The " (double quote) and the \ (backslash, aka escape)
        /// characters MUST be escaped (using the \ character) in the <b>variable</b>
        /// and <b>attribute</b> fields.</li>
        /// <p/>
        /// <li> The <b>variable</b> and <b>attribute</b> fields must be enclosed
        /// in double quotes if their values contain the dot (.) character.</li>
        /// <p/>
        /// <li> Fully qualified <b>variable</b> and <b>attribute</b> names always
        /// begin with the dot (.) character.</li>
        /// </ul>
        /// 
        /// </summary>
        /// <param name="field">The string to be tokenized.
        /// </param>
        /// <returns> The tokenized string.
        /// </returns>
        /// <throws>  MalformedAliasException </throws>
        public static ArrayList tokenizeAliasField(String field) {

            // find the index of the last element in the field.
            int lastIndex = field.Length - 1;

            // make a place to put the tokens.
            ArrayList tokens = ArrayList.Synchronized(new ArrayList(10));


            Trace.TraceInformation("lastIndexOf(dot): " + field.LastIndexOf(dot) + "   lastIndex: " +
                                      lastIndex);

            // Does this thing start with a quote?
            if (field[0] == quote) {
                // find the closing quote.
                // Because this token starts with a quote, it must be normalized
                // (see method description). The closing quote must exist,
                // and it cannont be escaped.

                // The first character in the token is the one following the
                // leadin quote.
                int start = 1;

                // prepare to Search for a closing quote.
                int end = - 1;
                bool done = false;
                bool escaped = false;

                // Search for the quote

                for (int i = 1; i <= lastIndex || !done; i++) {
                    char c = field[i];
                    //System.out.println("Checking for clear quote on char: "+c+" escaped="+escaped+"  done="+done);

                    // Was this character escaped (with a slash)?
                    if (escaped) {
                        // then ignore it and unset the escaped flag
                        // since the escape has been consumed.
                        escaped = false;
                    }
                    else {
                        // otherwise, is it an escape (slash) character
                        if (c == slash) {
                            // the set the escaoed flag to true.
                            escaped = true;
                        }
                        else if (c == quote) {
                            // if it's not an escape (slash) then is it a quote?

                            //System.out.println("Found quote!");

                            end = i;
                            done = true;
                        }
                    }
                }

                //System.out.println("start="+start+"  end="+end+"  lastIndex="+lastIndex);

                // if the end is less than 0 then it didn't get set
                // during the Search for the quote, and thus the closing quote wasn't
                // found. Throw an exception!
                if (end < 0)
                    throw new MalformedAliasException("Alias fields that begin with the quote (\") sign " +
                                                      "must have a closing quote.");

                // If there is more stuff, and that stuff is not seperated from the
                // closing quote by a dot character, then it's bad syntax.
                if (lastIndex > end && field[end + 1] != dot)
                    throw new MalformedAliasException("Alias fields must be seperated by the dot (.) character.");

                // The last caharcter in the field may not be an (unquoted) dot.
                if (field[lastIndex] == dot)
                    throw new MalformedAliasException("Alias fields may not end with the dot (.) character.");

                // Looks like we found a complete token.
                // Get it.
                String firstToken = field.Substring(start, (end) - (start));

                // Add it to the tokens Vector.
                tokens.Add(firstToken);

                // if there is more stuff, then tokenize it.
                if (end < lastIndex) {
                    // get the rest of the stuff
                    String theRest = field.Substring(end + 2);

                    // tokenize it and add each of the returned tokens to
                    // this tokens Vector.
                    // Recursive call.
                    IEnumerator tkns = tokenizeAliasField(theRest).GetEnumerator();
                    //UPGRADE_TODO: Method 'java.util.Enumeration.hasMoreElements' was converted to 'System.Collections.IEnumerator.MoveNext' which has a different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1073_javautilEnumerationhasMoreElements'"
                    while (tkns.MoveNext()) {
                        //UPGRADE_TODO: Method 'java.util.Enumeration.nextElement' was converted to 'System.Collections.IEnumerator.Current' which has a different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1073_javautilEnumerationnextElement'"
                        tokens.Add(tkns.Current);
                    }
                }

                return (tokens);
            }

            // Find the first dot. This simplistic Search is appropriate because
            // if this field contained a dot as part of it's name it should have
            // been encased in quotes and handled by the previous logic.

            int firstDot = field.IndexOf( dot);

            if (firstDot == 0) {
                // Does this thing start with dot?

                // Then it must be an absolute path.
                // NOTE: This should be true ONLY for the first token
                // in the list. By that I mean that a leading dot in
                // the field string should only occur when the
                // variable or alias field begins a dot. A secondary
                // token may only start with a dot if the dot is
                // actually part of the field, and thus it should be
                // encased in quotes.
                Trace.TraceInformation("First dot at index 0");
                String thisToken = ".";
                tokens.Add(thisToken);
                // Check to see if there are more characters in the field to be tokenized.
                // If there are, tokenize them.
                if (lastIndex > 0) {
                    String theRest = field.Substring(1);
                    // Recursive call
                    IEnumerator tkns = tokenizeAliasField(theRest).GetEnumerator();

                    // Take the tokens from the rest of the fields and
                    // add them to this token vector.
                    //UPGRADE_TODO: Method 'java.util.Enumeration.hasMoreElements' was converted to 'System.Collections.IEnumerator.MoveNext' which has a different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1073_javautilEnumerationhasMoreElements'"
                    while (tkns.MoveNext()) {
                        //UPGRADE_TODO: Method 'java.util.Enumeration.nextElement' was converted to 'System.Collections.IEnumerator.Current' which has a different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1073_javautilEnumerationnextElement'"
                        tokens.Add(tkns.Current);
                    }
                }
                return (tokens);
            }


            if (firstDot > 0) {
                // A secondary token may only contain a dot if the dot is
                // actually part of the field, and thus the field should have been
                // encased in quotes. Since we already check for a leading quote,
                // the first dor MUST be the end of the token.
                String firstToken = field.Substring(0, (firstDot) - (0));
                tokens.Add(firstToken);

                // A quick syntax check.
                if (lastIndex == firstDot)
                    throw new MalformedAliasException("Alias fields may not end with the dot (.) character.");

                // Get the rest of the field string
                String theRest = field.Substring(firstDot + 1);

                // tokenize it, and add it's tokens to this token Vector.
                IEnumerator tkns = tokenizeAliasField(theRest).GetEnumerator();
                //UPGRADE_TODO: Method 'java.util.Enumeration.hasMoreElements' was converted to 'System.Collections.IEnumerator.MoveNext' which has a different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1073_javautilEnumerationhasMoreElements'"
                while (tkns.MoveNext()) {
                    //UPGRADE_TODO: Method 'java.util.Enumeration.nextElement' was converted to 'System.Collections.IEnumerator.Current' which has a different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1073_javautilEnumerationnextElement'"
                    tokens.Add(tkns.Current);
                }

                return (tokens);
            }

            // This field string might be the final token, if we
            // get here it must be so add it to the tokens vector
            tokens.Add(field);

            return (tokens);
        }

        /// <summary> Prints the peristent representation of the <code>DDS</code> as an XML document.
        /// This XML document is know as a <b>DDX</b>. The DDX can be parsed using the
        /// <code>DDSXMLParser</code>
        /// 
        /// </summary>
        /// <param name="pw">The <code>StreamWriter</code> to Print to.
        /// </param>
        /// <opendap.ddx.experimental>  </opendap.ddx.experimental>
        public override void PrintXML(StreamWriter pw) {
            PrintXML(pw, "", false);
        }

        /// <summary> Prints the peristent representation of the <code>DDS</code> as an XML document.
        /// This XML document is know as a <b>DDX</b>. The DDX can be parsed using the
        /// <code>DDSXMLParser</code>
        /// 
        /// </summary>
        /// <param name="pw">         The <code>StreamWriter</code> to Print to.
        /// </param>
        /// <param name="pad">        A <code>String</code> to Print at the begining of each line.
        /// typically this is some white space.
        /// </param>
        /// <param name="constrained">A <code>bool</code> that indcates if the this call should
        /// Print the constrained version of the DDS. A value of <i>true</i> will cause the
        /// only the projected variables of the DDX to be printed .
        /// </param>
        /// <opendap.ddx.experimental>  </opendap.ddx.experimental>
        public override void PrintXML(StreamWriter pw, String pad, bool constrained) {
            //UPGRADE_TODO: Method 'java.io.StreamWriter.println' was converted to 'System.IO.TextWriter.WriteLine' which has a different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1073_javaioStreamWriterprintln_javalangString'"
            pw.WriteLine("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");

            //UPGRADE_TODO: Method 'java.io.StreamWriter.println' was converted to 'System.IO.TextWriter.WriteLine' which has a different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1073_javaioStreamWriterprintln_javalangString'"
            pw.WriteLine("<Dataset name=\"" + DDSXMLParser.normalizeToXML(Name) + "\"");
            //UPGRADE_TODO: Method 'java.io.StreamWriter.println' was converted to 'System.IO.TextWriter.WriteLine' which has a different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1073_javaioStreamWriterprintln_javalangString'"
            pw.WriteLine("xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"");
            //UPGRADE_TODO: Method 'java.io.StreamWriter.println' was converted to 'System.IO.TextWriter.WriteLine' which has a different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1073_javaioStreamWriterprintln_javalangString'"
            pw.WriteLine("xmlns=\"" + opendapNameSpace + "\"");
            pw.Write("xsi:schemaLocation=\"");
            pw.Write(opendapNameSpace + "  ");
            pw.Write(schemaLocation);
            //UPGRADE_TODO: Method 'java.io.StreamWriter.println' was converted to 'System.IO.TextWriter.WriteLine' which has a different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1073_javaioStreamWriterprintln_javalangString'"
            pw.WriteLine("\" >");
            //UPGRADE_TODO: Method 'java.io.StreamWriter.println' was converted to 'System.IO.TextWriter.WriteLine' which has a different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1073_javaioStreamWriterprintln_javalangString'"
            pw.WriteLine("");

            IEnumerator e = AttributeNames.GetEnumerator();
            //UPGRADE_TODO: Method 'java.util.Enumeration.hasMoreElements' was converted to 'System.Collections.IEnumerator.MoveNext' which has a different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1073_javautilEnumerationhasMoreElements'"
            while (e.MoveNext()) {
                //UPGRADE_TODO: Method 'java.util.Enumeration.nextElement' was converted to 'System.Collections.IEnumerator.Current' which has a different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1073_javautilEnumerationnextElement'"
                String aName = (String) e.Current;


                try {
                    Attribute a = GetAttribute(aName);
                    a.printXML(pw, pad + "\t", constrained);
                }
                catch (NoSuchAttributeException) {}
            }

            //UPGRADE_TODO: Method 'java.io.StreamWriter.println' was converted to 'System.IO.TextWriter.WriteLine' which has a different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1073_javaioStreamWriterprintln_javalangString'"
            pw.WriteLine("");

            IEnumerator ve = Variables;
            //UPGRADE_TODO: Method 'java.util.Enumeration.hasMoreElements' was converted to 'System.Collections.IEnumerator.MoveNext' which has a different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1073_javautilEnumerationhasMoreElements'"
            while (ve.MoveNext()) {
                //UPGRADE_TODO: Method 'java.util.Enumeration.nextElement' was converted to 'System.Collections.IEnumerator.Current' which has a different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1073_javautilEnumerationnextElement'"
                BaseType bt = (BaseType) ve.Current;
                bt.PrintXML(pw, pad + "\t", constrained);
            }

            //UPGRADE_TODO: Method 'java.io.StreamWriter.println' was converted to 'System.IO.TextWriter.WriteLine' which has a different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1073_javaioStreamWriterprintln_javalangString'"
            pw.WriteLine("");
            if (_dataBlobID != null) {
                //UPGRADE_TODO: Method 'java.io.StreamWriter.println' was converted to 'System.IO.TextWriter.WriteLine' which has a different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1073_javaioStreamWriterprintln_javalangString'"
                pw.WriteLine(pad + "\t" + "<dataBLOB href=\"" + DDSXMLParser.normalizeToXML(_dataBlobID) + "\"/>");
            }
            //UPGRADE_TODO: Method 'java.io.StreamWriter.println' was converted to 'System.IO.TextWriter.WriteLine' which has a different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1073_javaioStreamWriterprintln_javalangString'"
            pw.WriteLine(pad + "</Dataset>");
        }


        /// <summary> Takes the passed parameter <code>das</code> and attempts
        /// to incorporate it's contents into the Attributes of the DDS
        /// variables. If an <code>Attribute</code> in the <code>DAS</code>
        /// can't be associated with a variable in a logical manner then
        /// it is placed at the top level of the DDS. (Basically it becomes
        /// a toplevel attribute in the dataset)
        /// 
        /// </summary>
        /// <param name="das">The <code>DAS</code> to ingest.
        /// </param>
        /// <opendap.ddx.experimental>  </opendap.ddx.experimental>
        public virtual void ingestDAS(DAS das) {
            try {
                ingestAttributeTable(das, this);
                resolveAliases();
            }
            catch (DASException de) {
                //UPGRADE_TODO: The equivalent in .NET for method 'java.lang.Throwable.getMessage' may return a different value. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1043'"
                Console.Out.WriteLine("DDS.ingestDAS(): " + de.Message);
            }
        }

        /// <summary> A helper methods for ingestDAS().
        /// 
        /// </summary>
        /// <param name="a">
        /// </param>
        /// <param name="bt">
        /// </param>
        /// <throws>  DASException </throws>
        /// <seealso cref="ingestAttribute(Attribute, BaseType)">
        /// </seealso>
        /// <seealso cref="ingestAttributeTable(AttributeTable, BaseType)">
        /// </seealso>
        /// <seealso cref="ingestAttributeTable(AttributeTable, DConstructor)">
        /// </seealso>
        private void ingestAttribute(Attribute a, BaseType bt) {
            if (a.isAlias()) {
                // copy an alias.
                String name = a.Name;
                String attribute = ((Alias) a).AliasedToAttributeFieldAsClearString;

                bt.addAttributeAlias(name, attribute);
            }
            else if (a.isContainer()) {
                AttributeTable at = a.getContainer();
                ingestAttributeTable(at, bt);
            }
            else {
                // copy an Attribute and it's values...

                String name = a.Name;
                int type = a.Type;

                IEnumerator vals = a.Values;
                //UPGRADE_TODO: Method 'java.util.Enumeration.hasMoreElements' was converted to 'System.Collections.IEnumerator.MoveNext' which has a different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1073_javautilEnumerationhasMoreElements'"
                while (vals.MoveNext()) {
                    //UPGRADE_TODO: Method 'java.util.Enumeration.nextElement' was converted to 'System.Collections.IEnumerator.Current' which has a different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1073_javautilEnumerationnextElement'"
                    String value_Renamed = (String) vals.Current;
                    bt.AppendAttribute(name, type, value_Renamed, true);
                }
            }
        }


        /// <summary> A helper methods for ingestDAS().
        /// 
        /// </summary>
        /// <param name="at">
        /// </param>
        /// <param name="dc">
        /// </param>
        /// <throws>  DASException </throws>
        /// <seealso cref="ingestAttribute(Attribute, BaseType)">
        /// </seealso>
        /// <seealso cref="ingestAttributeTable(AttributeTable, BaseType)">
        /// </seealso>
        private void ingestAttributeTable(AttributeTable at, DConstructor dc) {
            IEnumerator ate = at.Names.GetEnumerator();

            //UPGRADE_TODO: Method 'java.util.Enumeration.hasMoreElements' was converted to 'System.Collections.IEnumerator.MoveNext' which has a different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1073_javautilEnumerationhasMoreElements'"
            while (ate.MoveNext()) {
                //UPGRADE_TODO: Method 'java.util.Enumeration.nextElement' was converted to 'System.Collections.IEnumerator.Current' which has a different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1073_javautilEnumerationnextElement'"
                String aName = (String) ate.Current;
                Attribute a = at.getAttribute(aName);
                bool foundIt = false;

                IEnumerator bte = dc.Variables;
                //UPGRADE_TODO: Method 'java.util.Enumeration.hasMoreElements' was converted to 'System.Collections.IEnumerator.MoveNext' which has a different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1073_javautilEnumerationhasMoreElements'"
                while (bte.MoveNext()) {
                    //UPGRADE_TODO: Method 'java.util.Enumeration.nextElement' was converted to 'System.Collections.IEnumerator.Current' which has a different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1073_javautilEnumerationnextElement'"
                    BaseType thisBT = (BaseType) bte.Current;
                    String bName = thisBT.Name;

                    if (bName.Equals(aName)) {
                        if (a.isContainer() && thisBT is DConstructor) {
                            ingestAttributeTable(a.getContainer(), (DConstructor) thisBT);
                        }
                        else {
                            ingestAttribute(a, thisBT);
                        }
                        foundIt = true;
                    }
                }

                if (!foundIt) {
                    ingestAttribute(a, dc);
                }
            }
        }

        /// <summary> A helper methods for ingestDAS().
        /// 
        /// </summary>
        /// <seealso cref="ingestAttribute(Attribute, BaseType)">
        /// </seealso>
        /// <seealso cref="ingestAttributeTable(AttributeTable, DConstructor)">
        /// </seealso>
        private void ingestAttributeTable(AttributeTable at, BaseType bt) {
            try {
                String atName = at.Name;
                String bName = bt.Name;
                //System.out.println("ingestATTbl: atName:"+atName+" bName: "+bName);

                if (bName.Equals(atName)) {
                    //System.out.println("adding each attribute!");
                    IEnumerator e = at.Names.GetEnumerator();
                    //UPGRADE_TODO: Method 'java.util.Enumeration.hasMoreElements' was converted to 'System.Collections.IEnumerator.MoveNext' which has a different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1073_javautilEnumerationhasMoreElements'"
                    while (e.MoveNext()) {
                        //UPGRADE_TODO: Method 'java.util.Enumeration.nextElement' was converted to 'System.Collections.IEnumerator.Current' which has a different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1073_javautilEnumerationnextElement'"
                        String aName = (String) e.Current;
                        Attribute a = at.getAttribute(aName);

                        ingestAttribute(a, bt);
                    }
                }
                else {
                    //System.out.println("addingcontainer!");
                    bt.addAttributeContainer(at);
                }
            }
            catch (AttributeExistsException) {
                IEnumerator e = at.Names.GetEnumerator();
                //UPGRADE_TODO: Method 'java.util.Enumeration.hasMoreElements' was converted to 'System.Collections.IEnumerator.MoveNext' which has a different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1073_javautilEnumerationhasMoreElements'"
                while (e.MoveNext()) {
                    //UPGRADE_TODO: Method 'java.util.Enumeration.nextElement' was converted to 'System.Collections.IEnumerator.Current' which has a different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1073_javautilEnumerationnextElement'"
                    String aName = (String) e.Current;
                    Attribute a = at.getAttribute(aName);

                    ingestAttribute(a, bt);
                }
            }
        }


        /// <summary> Check for name conflicts. In the XML representation
        /// of the DDS it is syntactically possible for a
        /// variable container (Dconstructor) to possess an
        /// Attribute that has the same name as one of the container
        /// variable's member variables. That's a NO-NO!.
        /// Check for it here and throw a nice fat exception if we find it.
        /// </summary>
        public virtual void CheckForAttributeNameConflict() {
            CheckForAttributeNameConflict(this);
        }


        /// <summary> Check for name conflicts. In the XML representation
        /// of the DDS it is syntactically possible for a
        /// variable container (Dconstructor) to possess an
        /// Attribute that has the same name as one of the container
        /// variable's member variables. That's a NO-NO!.
        /// Check for it here and throw a nice fat exception if we find it.
        /// 
        /// </summary>
        /// <param name="dc">The <code>DConstructor</code> to Search for name conflicts.
        /// </param>
        private static void CheckForAttributeNameConflict(DConstructor dc) {
            //System.out.println("Checking "+dc.getTypeName()+" "+dc.getName()+" for name conflicts.");

            IEnumerator bte = dc.Variables;
            //UPGRADE_TODO: Method 'java.util.Enumeration.hasMoreElements' was converted to 'System.Collections.IEnumerator.MoveNext' which has a different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1073_javautilEnumerationhasMoreElements'"
            while (bte.MoveNext()) {
                //UPGRADE_TODO: Method 'java.util.Enumeration.nextElement' was converted to 'System.Collections.IEnumerator.Current' which has a different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1073_javautilEnumerationnextElement'"
                BaseType bt = (BaseType) bte.Current;

                //System.out.println("     member: "+bt.getTypeName()+" "+bt.getName());
                IEnumerator ate = dc.AttributeNames.GetEnumerator();
                //UPGRADE_TODO: Method 'java.util.Enumeration.hasMoreElements' was converted to 'System.Collections.IEnumerator.MoveNext' which has a different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1073_javautilEnumerationhasMoreElements'"
                while (ate.MoveNext()) {
                    //UPGRADE_TODO: Method 'java.util.Enumeration.nextElement' was converted to 'System.Collections.IEnumerator.Current' which has a different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1073_javautilEnumerationnextElement'"
                    String aName = (String) ate.Current;

                    //System.out.println("         attribute: "+aName);
                    if (aName.Equals(bt.Name)) {
                        throw new BadSemanticsException("The variable '" + dc.LongName +
                                                        "' has an Attribute with the same name ('" + aName +
                                                        "') as one of it's " + "member variables (" + bt.TypeName + " " +
                                                        bt.Name + ")\n" + "This is NOT allowed.");
                    }
                }

                if (bt is DConstructor) {
                    // System.out.println("     member '"+bt.getName()+"' is a container. Better Check it!");
                    // Recursive call!!
                    CheckForAttributeNameConflict((DConstructor) bt);
                }
            }
        }
    }
}